import { useState, useEffect, useRef, useCallback } from "react";
import videos from "../../../assets/video.mp4";
import { Form, Input, message } from "antd";
import style from "../style.module.css";
import axios from "axios";
import { SettingOutlined } from '@ant-design/icons';

// 弹幕类型定义
interface Danmaku {
  id: string;
  content: string;
  time: number; // 弹幕应出现的时间（秒）
  senderId: string;
  color: string;
  type: number; // 0:滚动 1:顶部 2:底部
}

// 按时间分组的弹幕
type DanmakuTimeline = Map<number, Danmaku[]>;

// 弹幕位置信息
interface DanmakuPosition {
  top: string;
  left: string;
}

function App() {
  // 视频和容器相关引用
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const containerRef = useRef<HTMLDivElement | null>(null);
  const xz = useRef<HTMLDivElement>(null);
  
  // 状态管理
  const [inputValue, setInputValue] = useState("");
  const [videoHeight, setVideoHeight] = useState(460);
  const [videoPaused, setVideoPaused] = useState(false);
  const [form] = Form.useForm();
  
  // 弹幕样式配置状态
  const [danmakuColor, setDanmakuColor] = useState("#fff"); // 默认紫色
  const [danmakuSize, setDanmakuSize] = useState(16); // 默认字体大小
  const [danmakuPosition, setDanmakuPosition] = useState(0); // 默认滚动
  
  // 预设颜色选项
  const colorOptions = [
    { value: "#ffffff", label: "白色" },
    { value: "#ff0000", label: "红色" },
    { value: "#00ff00", label: "绿色" },
    { value: "#0000ff", label: "蓝色" },
    { value: "#ffff00", label: "黄色" },
    { value: "#ff00ff", label: "紫色" },
    { value: "#00ffff", label: "青色" },
    { value: "#ff8800", label: "橙色" },
    { value: "#8800ff", label: "靛蓝" },
    { value: "#00ff88", label: "翡翠绿" },
    { value: "#ff0088", label: "粉红" },
    { value: "#888888", label: "灰色" },
  ];

  // 弹幕数据管理
  const danmakuTimeline = useRef<DanmakuTimeline>(new Map());
  const renderedDanmakus = useRef(new Set<string>());
  const danmakuPositions = useRef<Map<string, DanmakuPosition>>(new Map());
  const animationFrameId = useRef<number | null>(null);

  // 用户和视频标识
  const userId = useRef("user_" + Math.random().toString(36).substr(2, 9)).current;
  const videoId = "demo_video_1";
  const apiBaseUrl = "http://localhost:5000";

  // 添加弹幕到时间轴（带去重）
  const addDanmakuToTimeline = useCallback((danmaku: Danmaku) => {
    const timeKey = Math.floor(danmaku.time);
    if (!danmakuTimeline.current.has(timeKey)) {
      danmakuTimeline.current.set(timeKey, []);
    }
    const existingDanmakus = danmakuTimeline.current.get(timeKey)!;
    if (!existingDanmakus.some(d => d.id === danmaku.id)) {
      existingDanmakus.push(danmaku);
    }
  }, []);

  // 从时间轴移除弹幕
  const removeDanmakuFromTimeline = useCallback((danmakuId: string) => {
    danmakuTimeline.current.forEach((danmakus, timeKey) => {
      const index = danmakus.findIndex(d => d.id === danmakuId);
      if (index !== -1) {
        danmakus.splice(index, 1);
        if (danmakus.length === 0) {
          danmakuTimeline.current.delete(timeKey);
        }
      }
    });
  }, []);

  // 更新时间轴中的弹幕
  const updateDanmakuInTimeline = useCallback((updatedDanmaku: Danmaku) => {
    danmakuTimeline.current.forEach((danmakus) => {
      const index = danmakus.findIndex(d => d.id === updatedDanmaku.id);
      if (index !== -1) {
        danmakus[index] = updatedDanmaku;
      }
    });
  }, []);

  // 获取指定时间范围内的弹幕
  const getDanmakusInRange = useCallback((startTime: number, endTime: number) => {
    const result: Danmaku[] = [];
    const startKey = Math.floor(startTime);
    const endKey = Math.floor(endTime);

    for (let key = startKey; key <= endKey; key++) {
      const danmakus = danmakuTimeline.current.get(key);
      if (danmakus) {
        result.push(...danmakus.filter(d => d.time >= startTime && d.time <= endTime));
      }
    }

    return result;
  }, []);

  // 生成并缓存弹幕的垂直位置
  const getOrGenerateVerticalPosition = useCallback((danmu: Danmaku) => {
    if (danmakuPositions.current.has(danmu.id)) {
      return danmakuPositions.current.get(danmu.id)!;
    }

    const maxTop = videoHeight * 0.66;
    const position: DanmakuPosition = {
      top: `${Math.random() * maxTop}px`,
      left: "100%", // 初始位置在屏幕右侧
    };

    danmakuPositions.current.set(danmu.id, position);
    return position;
  }, [videoHeight]);

  // 计算弹幕样式
  const getDanmakuStyle = useCallback((danmu: Danmaku, progress: number) => {
    const isCurrentUser = danmu.senderId === userId;

    const baseStyle: React.CSSProperties = {
      color: isCurrentUser ? danmakuColor : danmu.color,
      fontSize: `${isCurrentUser ? danmakuSize : 16}px`,
      whiteSpace: "nowrap",
      position: "absolute",
      willChange: "transform",
      pointerEvents: isCurrentUser ? "auto" : "none",
      transition: "left 0.1s linear",
      textShadow: "0 0 2px rgba(0,0,0,0.5)", // 增加文字阴影提升可读性
      zIndex: 10,
    };

    if (danmu.type === 0) {
      const position = getOrGenerateVerticalPosition(danmu);
      return {
        ...baseStyle,
        top: position.top,
        left: `${100 - progress * 200}%`,
      };
    } else if (danmu.type === 1) {
      return {
        ...baseStyle,
        top: "10%",
        left: "50%",
        transform: "translateX(-50%)",
      };
    } else {
      return {
        ...baseStyle,
        bottom: "10%",
        left: "50%",
        transform: "translateX(-50%)",
      };
    }
  }, [getOrGenerateVerticalPosition, userId, danmakuColor, danmakuSize]);

  // 删除弹幕
  const deleteDanmaku = useCallback(async (danmakuId: string) => {
    try {
      await axios.delete(`${apiBaseUrl}/danmaku/${videoId}/${danmakuId}`, {
        data: { senderId: userId }
      });

      removeDanmakuFromTimeline(danmakuId);

      if (containerRef.current) {
        const danmakuEl = containerRef.current.querySelector(`[data-danmaku-id="${danmakuId}"]`);
        if (danmakuEl) {
          containerRef.current.removeChild(danmakuEl);
          renderedDanmakus.current.delete(danmakuId);
          danmakuPositions.current.delete(danmakuId);
        }
      }

      message.success("弹幕删除成功");

      if (videoRef.current && videoRef.current.paused) {
        videoRef.current.play();
      }
    } catch (error) {
      console.error("删除弹幕失败:", error);
      message.error("删除失败，请重试");
    }
  }, [videoId, userId, removeDanmakuFromTimeline]);

  // 渲染弹幕
  const renderDanmakus = useCallback(() => {
    if (!videoRef.current || !containerRef.current) return;

    const video = videoRef.current;
    const container = containerRef.current;
    const now = video.currentTime;

    // 清除超出显示范围的弹幕
    Array.from(container.children).forEach(child => {
      const danmakuId = child.getAttribute("data-danmaku-id");
      if (!danmakuId) return;

      const time = parseFloat(child.getAttribute("data-time") || "0");
      if (Math.abs(time - now) > 10) {
        container.removeChild(child);
        renderedDanmakus.current.delete(danmakuId);
        danmakuPositions.current.delete(danmakuId);
      }
    });

    // 获取当前时间窗口内的所有弹幕
    const visibleDanmakus = getDanmakusInRange(now - 10, now + 10);

    // 渲染新弹幕
    visibleDanmakus.forEach(danmaku => {
      if (renderedDanmakus.current.has(danmaku.id)) return;

      const div = document.createElement("div");
      div.className = style["danmaku-item"];
      div.setAttribute("data-danmaku-id", danmaku.id);
      div.setAttribute("data-time", danmaku.time.toString());
      div.setAttribute("data-sender", danmaku.senderId);

      const timeDiff = now - danmaku.time;
      const progress = Math.max(0, Math.min(1, timeDiff / 8));

      // 应用样式
      Object.assign(div.style, getDanmakuStyle(danmaku, progress));

      // 判断是否为当前用户的弹幕
      const isCurrentUser = danmaku.senderId === userId;

      // 正常状态：显示内容和操作按钮（仅当前用户可见）
      div.innerHTML = `
        <span class="danmaku-content">${danmaku.content}</span>
        ${isCurrentUser ? `
          <div class="${style['danmaku-actions']}">
            <button class="${style['edit-btn']}" data-id="${danmaku.id}">编辑</button>
            <button class="${style['delete-btn']}" data-id="${danmaku.id}">删除</button>
          </div>
        ` : ''}
      `;

      // 绑定弹幕点击事件（暂停视频和弹幕）
      div.onclick = (e) => {
        e.stopPropagation();
        if (!video.paused) {
          video.pause();
        }
        if (animationFrameId.current) {
          cancelAnimationFrame(animationFrameId.current);
          animationFrameId.current = null;
        }
      };

      // 绑定编辑/删除按钮事件
      if (isCurrentUser) {
        const editBtn = div.querySelector(`.${style['edit-btn']}`) as HTMLButtonElement;
        const deleteBtn = div.querySelector(`.${style['delete-btn']}`) as HTMLButtonElement;

        editBtn.onclick = (e) => {
          e.stopPropagation();
          startEditMode(div, danmaku);
        };

        deleteBtn.onclick = (e) => {
          e.stopPropagation();
          if (window.confirm("确定要删除这条弹幕吗？")) {
            deleteDanmaku(danmaku.id);
            if (video.paused) {
              video.play();
            }
          }
        };
      }

      container.appendChild(div);
      renderedDanmakus.current.add(danmaku.id);
    });

    // 更新所有可见弹幕的位置
    Array.from(container.children).forEach(child => {
      const danmakuId = child.getAttribute("data-danmaku-id");
      if (!danmakuId) return;

      const time = parseFloat(child.getAttribute("data-time") || "0");
      const timeDiff = now - time;

      if (timeDiff < 0 || timeDiff > 8) return;

      const danmaku = visibleDanmakus.find(d => d.id === danmakuId);
      if (danmaku) {
        const progress = timeDiff / 8;
        Object.assign((child as HTMLElement).style, getDanmakuStyle(danmaku, progress));
      }
    });

    animationFrameId.current = requestAnimationFrame(renderDanmakus);
  }, [getDanmakusInRange, getDanmakuStyle, deleteDanmaku]);

  // 开始编辑模式
  const startEditMode = useCallback((danmakuDiv: HTMLElement, danmaku: Danmaku) => {
    const originalContent = danmaku.content;

    // 转换为编辑模式
    danmakuDiv.setAttribute("data-editing", "true");
    danmakuDiv.innerHTML = `
      <input 
        type="text" 
        class="${style['edit-input']}" 
        value="${originalContent}"
      />
      <button class="${style['edit-confirm']}">确认</button>
      <button class="${style['edit-cancel']}">取消</button>
    `;

    const inputEl = danmakuDiv.querySelector(`.${style['edit-input']}`) as HTMLInputElement;
    const confirmBtn = danmakuDiv.querySelector(`.${style['edit-confirm']}`) as HTMLButtonElement;
    const cancelBtn = danmakuDiv.querySelector(`.${style['edit-cancel']}`) as HTMLButtonElement;

    // 聚焦输入框
    setTimeout(() => {
      inputEl.focus();
      inputEl.select();
    }, 10);

    // 确认编辑
    confirmBtn.onclick = async () => {
      const newContent = inputEl.value.trim();
      if (!newContent) return;

      try {
        const response = await axios.patch(
          `${apiBaseUrl}/danmaku/${videoId}/${danmaku.id}`,
          {
            senderId: userId,
            content: newContent,
            color: danmakuColor, // 同步颜色
            type: danmakuPosition // 同步位置
          }
        );

        const updatedDanmaku: Danmaku = response.data.danmaku;
        updateDanmakuInTimeline(updatedDanmaku);

        // 恢复弹幕显示
        danmakuDiv.removeAttribute("data-editing");
        danmakuDiv.innerHTML = `
          <span class="danmaku-content">${updatedDanmaku.content}</span>
          <div class="${style['danmaku-actions']}">
            <button class="${style['edit-btn']}" data-id="${updatedDanmaku.id}">编辑</button>
            <button class="${style['delete-btn']}" data-id="${updatedDanmaku.id}">删除</button>
          </div>
        `;

        // 重新绑定事件
        const editBtn = danmakuDiv.querySelector(`.${style['edit-btn']}`) as HTMLButtonElement;
        const deleteBtn = danmakuDiv.querySelector(`.${style['delete-btn']}`) as HTMLButtonElement;

        editBtn.onclick = (e) => {
          e.stopPropagation();
          startEditMode(danmakuDiv, updatedDanmaku);
        };

        deleteBtn.onclick = (e) => {
          e.stopPropagation();
          if (window.confirm("确定要删除这条弹幕吗？")) {
            deleteDanmaku(updatedDanmaku.id);
          }
        };

        message.success("弹幕编辑成功");

        if (videoRef.current && videoRef.current.paused) {
          videoRef.current.play();
        }
      } catch (error) {
        console.error("编辑弹幕失败:", error);
        message.error("编辑失败，请重试");
      }
    };

    // 取消编辑
    cancelBtn.onclick = () => {
      // 恢复原始显示
      danmakuDiv.removeAttribute("data-editing");
      danmakuDiv.innerHTML = `
        <span class="danmaku-content">${originalContent}</span>
        <div class="${style['danmaku-actions']}">
          <button class="${style['edit-btn']}" data-id="${danmaku.id}">编辑</button>
          <button class="${style['delete-btn']}" data-id="${danmaku.id}">删除</button>
        </div>
      `;

      // 重新绑定事件
      const editBtn = danmakuDiv.querySelector(`.${style['edit-btn']}`) as HTMLButtonElement;
      const deleteBtn = danmakuDiv.querySelector(`.${style['delete-btn']}`) as HTMLButtonElement;

      editBtn.onclick = (e) => {
        e.stopPropagation();
        startEditMode(danmakuDiv, danmaku);
      };

      deleteBtn.onclick = (e) => {
        e.stopPropagation();
        if (window.confirm("确定要删除这条弹幕吗？")) {
          deleteDanmaku(danmaku.id);
        }
      };

      if (videoRef.current && videoRef.current.paused) {
        videoRef.current.play();
      }
    };
  }, [videoId, userId, updateDanmakuInTimeline, deleteDanmaku, danmakuColor, danmakuPosition]);

  // 获取弹幕数据
  const fetchDanmakus = useCallback(async () => {
    try {
      const currentTime = videoRef.current?.currentTime || 0;
      const response = await axios.get(
        `${apiBaseUrl}/danmaku/${videoId}`,
        { params: { currentTime } }
      );

      const newDanmakus: Danmaku[] = response.data;

      // 去重添加
      newDanmakus.forEach(danmaku => {
        const timeKey = Math.floor(danmaku.time);
        const existingDanmakus = danmakuTimeline.current.get(timeKey) || [];
        const isDuplicate = existingDanmakus.some(d => d.id === danmaku.id);

        if (!isDuplicate) {
          existingDanmakus.push(danmaku);
          danmakuTimeline.current.set(timeKey, existingDanmakus);
        }
      });

      renderDanmakus();
    } catch (error) {
      console.error("获取弹幕失败:", error);
    }
  }, [videoId, renderDanmakus]);

  // 发送弹幕
  const sendDanmaku = useCallback(async () => {
    if (!inputValue.trim() || !videoRef.current) return;

    const videoTime = videoRef.current.currentTime;

    try {
      const response = await axios.post(`${apiBaseUrl}/danmaku`, {
        videoId,
        content: inputValue,
        time: videoTime,
        senderId: userId,
        color: danmakuColor, // 使用选择的颜色
        type: danmakuPosition, // 使用选择的位置
      });

      const serverDanmaku: Danmaku = response.data;

      // 清空输入框
      form.resetFields();
      setInputValue("");

      // 本地添加
      addDanmakuToTimeline(serverDanmaku);
      renderDanmakus();

    } catch (error) {
      console.error("发送弹幕失败:", error);
      message.error("发送失败，请重试");
    }
  }, [inputValue, addDanmakuToTimeline, renderDanmakus, form, userId, videoId, danmakuColor, danmakuPosition]);

  // 切换设置面板显示状态
  const check = () => {
    if (xz.current) {
      xz.current.className = xz.current.className === 'show' ? 'hidden' : 'show';
    }
  };

  // 监听视频事件
  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const handlePlay = () => {
      setVideoPaused(false);
      if (!animationFrameId.current) {
        animationFrameId.current = requestAnimationFrame(renderDanmakus);
      }
    };

    const handlePause = () => {
      setVideoPaused(true);
      if (animationFrameId.current) {
        cancelAnimationFrame(animationFrameId.current);
        animationFrameId.current = null;
      }
    };

    const handleTimeUpdate = () => {
      if (Math.floor(video.currentTime) % 5 === 0) {
        fetchDanmakus();
      }
    };

    const handleSeek = () => {
      renderDanmakus();
    };

    const handleResize = () => {
      setVideoHeight(video.clientHeight);
      danmakuPositions.current.clear();
      renderDanmakus();
    };

    video.addEventListener("play", handlePlay);
    video.addEventListener("pause", handlePause);
    video.addEventListener("timeupdate", handleTimeUpdate);
    video.addEventListener("seeked", handleSeek);

    const resizeObserver = new ResizeObserver(handleResize);
    resizeObserver.observe(video);

    fetchDanmakus();

    // 清理函数
    return () => {
      video.removeEventListener("play", handlePlay);
      video.removeEventListener("pause", handlePause);
      video.removeEventListener("timeupdate", handleTimeUpdate);
      video.removeEventListener("seeked", handleSeek);
      resizeObserver.disconnect();

      if (animationFrameId.current) {
        cancelAnimationFrame(animationFrameId.current);
      }

      if (containerRef.current) {
        containerRef.current.innerHTML = "";
      }

      renderedDanmakus.current.clear();
      danmakuTimeline.current.clear();
      danmakuPositions.current.clear();
    };
  }, [renderDanmakus, fetchDanmakus]);

  // 监听视频高度变化
  useEffect(() => {
    danmakuPositions.current.clear();
    renderDanmakus();
  }, [videoHeight, renderDanmakus]);

  return (
    <div className={style["danmaku-system"]}>
      <div className={style["video-container"]}>
        <div className={style["video-wrapper"]}>
          <video
            ref={videoRef}
            src={videos}
            width="800"
            height="560"
            controls
            loop
            muted
            autoPlay
          />
          <div ref={containerRef} className={style["danmaku-container"]} />

          {/* 恢复播放按钮 */}
          {videoPaused && (
            <div
              className={style["resume-button"]}
              onClick={() => {
                if (videoRef.current) {
                  videoRef.current.play();
                }
              }}
            >
              ▶️ 恢复播放
            </div>
          )}
        </div>
      </div>
      
      <div className={style["danmaku-controls"]}>
        <Form form={form} layout="inline">
          <Form.Item>
            <SettingOutlined 
              style={{ color: '#fff', fontSize: '20px', cursor: 'pointer' }} 
              onClick={check} 
            />
            {/* 设置面板 */}
            <div 
              ref={xz} 
              className='hidden' 
              style={{ 
                width: '240px',
                padding: '15px',
                background: 'rgba(50, 50, 50, 0.9)',
                position: 'absolute',
                top: '-340px',
                left: '0',
                borderRadius: '8px',
                zIndex: 100,
                boxShadow: '0 2px 10px rgba(0,0,0,0.3)'
              }}
            >
              {/* 颜色选择 */}
              <div style={{ marginBottom: '15px' }}>
                <span style={{ color: '#fff', display: 'block', marginBottom: '8px' }}>颜色：</span>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
                  {colorOptions.map(option => (
                    <button
                      key={option.value}
                      style={{
                        width: '30px',
                        height: '30px',
                        borderRadius: '50%',
                        backgroundColor: option.value,
                        border: danmakuColor === option.value ? '2px solid #fff' : '2px solid transparent',
                        cursor: 'pointer',
                        position: 'relative',
                        overflow: 'hidden',
                        transition: 'transform 0.2s'
                      }}
                      onClick={() => setDanmakuColor(option.value)}
                      title={option.label}
                      onMouseOver={(e) => (e.target as HTMLButtonElement).style.transform = 'scale(1.1)'}
                      onMouseOut={(e) => (e.target as HTMLButtonElement).style.transform = 'scale(1)'}
                    >
                      {danmakuColor === option.value && (
                        <span style={{
                          position: 'absolute',
                          top: '50%',
                          left: '50%',
                          transform: 'translate(-50%, -50%)',
                          color: '#000',
                          fontWeight: 'bold',
                          fontSize: '12px'
                        }}>✓</span>
                      )}
                    </button>
                  ))}
                </div>
              </div>
              
              {/* 字体大小 */}
              <div style={{ marginBottom: '15px' }}>
                <span style={{ color: '#fff', display: 'block', marginBottom: '8px' }}>
                  大小: {danmakuSize}px
                </span>
                <input
                  type="range"
                  min="12"
                  max="32"
                  step="2"
                  value={danmakuSize}
                  onChange={(e) => setDanmakuSize(Number(e.target.value))}
                  style={{
                    width: '100%',
                    cursor: 'pointer'
                  }}
                />
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '12px', color: '#ccc', marginTop: '5px' }}>
                  <span>小</span>
                  <span>大</span>
                </div>
              </div>
              
              {/* 弹幕位置 */}
              <div>
                <span style={{ color: '#fff', display: 'block', marginBottom: '8px' }}>弹幕位置</span>
                <div style={{ display: 'flex', gap: '10px' }}>
                  <button
                    onClick={() => setDanmakuPosition(0)}
                    style={{
                      flex: 1,
                      padding: '5px 0',
                      border: danmakuPosition === 0 ? '2px solid #fff' : '1px solid #666',
                      background: 'transparent',
                      color: '#fff',
                      cursor: 'pointer',
                      borderRadius: '4px',
                      transition: 'all 0.2s'
                    }}
                  >
                    滚动
                  </button>
                  <button
                    onClick={() => setDanmakuPosition(1)}
                    style={{
                      flex: 1,
                      padding: '5px 0',
                      border: danmakuPosition === 1 ? '2px solid #fff' : '1px solid #666',
                      background: 'transparent',
                      color: '#fff',
                      cursor: 'pointer',
                      borderRadius: '4px',
                      transition: 'all 0.2s'
                    }}
                  >
                    顶部
                  </button>
                  <button
                    onClick={() => setDanmakuPosition(2)}
                    style={{
                      flex: 1,
                      padding: '5px 0',
                      border: danmakuPosition === 2 ? '2px solid #fff' : '1px solid #666',
                      background: 'transparent',
                      color: '#fff',
                      cursor: 'pointer',
                      borderRadius: '4px',
                      transition: 'all 0.2s'
                    }}
                  >
                    底部
                  </button>
                </div>
              </div>
            </div>
          </Form.Item>
          
          <Form.Item
            name="content"
            rules={[{ required: true, message: "请输入弹幕内容" }]}
          >
            <Input.Search
              value={inputValue}
              onChange={(e) => setInputValue(e.target.value)}
              placeholder="输入弹幕内容"
              enterButton="发送"
              onSearch={(value) => {
                if (value.trim()) sendDanmaku();
              }}
              style={{ width: 300 }}
              onPressEnter={(e) => {
                e.preventDefault();
                if (inputValue.trim()) sendDanmaku();
              }}
            />
          </Form.Item>
        </Form>
      </div>
    </div>
  );
}

export default App;